package main

import (
	"fmt"
	"sync"
	"time"
)

type mutex struct {
	ch     chan struct{}
	locked bool
}

func getMutex() *mutex {
	return &mutex{
		ch:     make(chan struct{}, 1),
		locked: false,
	}
}

func (m *mutex) Lock() bool {

	select {
	case m.ch <- struct{}{}:
		m.locked = true
		return true
	case <-time.After(time.Second):
		return false
	}
}

func (m *mutex) UnLock() {

	if m.locked {
		<-m.ch
		m.locked = false
	}
}

func main() {

	m := getMutex()
	wg := sync.WaitGroup{}
	wg.Add(2)
	for i := 0; i < 2; i++ {
		go func() {
			if m.Lock() {
				fmt.Println("locked")
				time.Sleep(time.Second * 2)
				fmt.Println("un locked")
			} else {
				fmt.Println("no locked")
			}
			defer wg.Done()
		}()
	}
	wg.Wait()
}
